import { _decorator, Input, input, KeyCode, Vec2} from 'cc';
import Singleton from './Singleton';
import EventManager from './EventManager';
import { PARAMS_NAME_ENUM } from '../Enum';

const { ccclass, property } = _decorator;

@ccclass('InputManager')
export class InputManager extends Singleton {
    // 输入状态
    private lastADKey: KeyCode = null;
    private lastWSKey: KeyCode = null;
    public moveDir: Vec2 = new Vec2();  // 移动方向向量
    public pressJump: boolean = false;  // 跳跃状态
    public pressDash: boolean = false;  // 冲刺状态
    public keyState: Map<KeyCode, boolean> = new Map();  // 按键状态映射

    
    // 输入配置
    public jumpKeys: KeyCode[] = [KeyCode.SPACE, KeyCode.KEY_C, KeyCode.KEY_K];
    
    public dashKeys: KeyCode[] = [KeyCode.SHIFT_LEFT, KeyCode.KEY_X, KeyCode.KEY_J];
    
    public leftKeys: KeyCode[] = [KeyCode.KEY_A, KeyCode.ARROW_LEFT];
    
    public rightKeys: KeyCode[] = [KeyCode.KEY_D, KeyCode.ARROW_RIGHT];
    
    public downKeys: KeyCode[] = [KeyCode.KEY_S, KeyCode.ARROW_DOWN];
    
    public upKeys: KeyCode[] = [KeyCode.KEY_W, KeyCode.ARROW_UP];
    
    // 触摸控制配置
    public joystickRadius: Vec2 = new Vec2(100, 100);
    
    // 单例访问
    static get Instance() {
        return super.GetInstance<InputManager>();
    }
    
    // 初始化输入监听
    init() {
        console.log('InputManager 初始化输入监听');
        // 键盘输入监听
        input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
    }
    
    // 清理资源
    onDestroy(): void {
        input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
        input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
    }
    
    // 键盘按下事件
    private onKeyDown(event): void {
        const keyCode = event.keyCode;
        if (this.keyState.get(keyCode)) return; // 防止重复触发
        
        this.keyState.set(keyCode, true);
        
        // 更新最后按下的方向键（立即更新）
        if (this.leftKeys.includes(keyCode) || this.rightKeys.includes(keyCode)) {
            this.lastADKey = keyCode;
        }
        if (this.upKeys.includes(keyCode) || this.downKeys.includes(keyCode)) {
            this.lastWSKey = keyCode;
        }
        // 更新移动方向
        this.updateMoveDirection();
        
        // 跳跃检测
        if (this.jumpKeys.includes(keyCode)) {
            this.pressJump = true;
            EventManager.Instance.emit(PARAMS_NAME_ENUM.JUMP);
        }
        
        // 冲刺检测
        if (this.dashKeys.includes(keyCode)) {
            this.pressDash = true;
            EventManager.Instance.emit(PARAMS_NAME_ENUM.DASH);
        }
    }
    
    // 键盘释放事件
    private onKeyUp(event): void {
        const keyCode = event.keyCode;
        this.keyState.set(keyCode, false);
        
        // 水平方向释放处理
        if (keyCode === this.lastADKey) {
            // 检查是否有其他按下的左右键
            this.lastADKey = null;
            
            // 优先检查右侧键
            for (const key of this.rightKeys) {
                if (this.keyState.get(key)) {
                    this.lastADKey = key;
                    break;
                }
            }
            
            // 如果没有右侧键再检查左侧键
            if (this.lastADKey === null) {
                for (const key of this.leftKeys) {
                    if (this.keyState.get(key)) {
                        this.lastADKey = key;
                        break;
                    }
                }
            }
        }

        // 垂直方向释放处理
        if (keyCode === this.lastWSKey) {
            // 检查是否有其他按下的上下键
            this.lastWSKey = null;
            
            // 优先检查上方键
            for (const key of this.upKeys) {
                if (this.keyState.get(key)) {
                    this.lastWSKey = key;
                    break;
                }
            }
        
            // 如果没有上方键再检查下方键
            if (this.lastWSKey === null) {
                for (const key of this.downKeys) {
                    if (this.keyState.get(key)) {
                        this.lastWSKey = key;
                        break;
                    }
                }
            }
        }
        
        // 更新移动方向
        this.updateMoveDirection();
        
        // 跳跃释放
        if (this.jumpKeys.includes(keyCode)) {
            this.pressJump = false;
        }
        
        // 冲刺释放
        if (this.dashKeys.includes(keyCode)) {
            this.pressDash = false;
        }
    }
    
    // 更新移动方向 (键盘)
    private updateMoveDirection(): void {
        let x = 0;
        if (this.lastADKey !== null) {
            if (this.rightKeys.includes(this.lastADKey)) {
                x = 1;
            } else if (this.leftKeys.includes(this.lastADKey)) {
                x = -1;
            }
        }
        let y = 0;
        if (this.lastWSKey !== null) {
            if (this.upKeys.includes(this.lastWSKey)) {
                y = 1; 
            } else if (this.downKeys.includes(this.lastWSKey)) {
                y = -1; 
            }
        }
        // 更新移动方向向量
        this.moveDir.set(x, y);
    }

}